import json
from typing import Dict, List, Optional
from datetime import datetime
from demo.models.schemas import DevicePlatformBinding, PlatformInfo, BindRequest
import aiosqlite
import uuid


class BindingManager:
    def __init__(self, db_path: str = "device_management.db"):
        self.db_path = db_path
        self.platforms: Dict[str, PlatformInfo] = {}
        self.active_bindings: Dict[str, DevicePlatformBinding] = {}
        self.init_default_platforms()

    def init_default_platforms(self):
        """初始化默认平台信息"""
        default_platforms = [
            PlatformInfo(
                platform_id="android_platform",
                platform_name="Android管理平台",
                platform_type="android",
                version="1.0.0",
                description="Android设备管理平台",
                api_endpoint="/api/android"
            ),
            PlatformInfo(
                platform_id="ios_platform",
                platform_name="iOS管理平台",
                platform_type="ios",
                version="1.0.0",
                description="iOS设备管理平台",
                api_endpoint="/api/ios"
            ),
            PlatformInfo(
                platform_id="web_platform",
                platform_name="Web管理平台",
                platform_type="web",
                version="1.0.0",
                description="Web设备管理平台",
                api_endpoint="/api/web"
            )
        ]

        for platform in default_platforms:
            self.platforms[platform.platform_id] = platform

    async def init_db(self):
        """初始化数据库"""
        async with aiosqlite.connect(self.db_path) as db:
            await db.execute('''
                CREATE TABLE IF NOT EXISTS device_platform_bindings (
                    binding_id TEXT PRIMARY KEY,
                    device_id TEXT NOT NULL,
                    platform_id TEXT NOT NULL,
                    bind_time TIMESTAMP NOT NULL,
                    unbind_time TIMESTAMP,
                    is_active BOOLEAN NOT NULL DEFAULT 1,
                    bind_config TEXT,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )
            ''')

            await db.execute('''
                CREATE TABLE IF NOT EXISTS platforms (
                    platform_id TEXT PRIMARY KEY,
                    platform_name TEXT NOT NULL,
                    platform_type TEXT NOT NULL,
                    version TEXT NOT NULL,
                    description TEXT,
                    api_endpoint TEXT,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )
            ''')

            # 插入默认平台数据
            for platform in self.platforms.values():
                await db.execute('''
                    INSERT OR IGNORE INTO platforms 
                    (platform_id, platform_name, platform_type, version, description, api_endpoint)
                    VALUES (?, ?, ?, ?, ?, ?)
                ''', (
                    platform.platform_id, platform.platform_name, platform.platform_type,
                    platform.version, platform.description, platform.api_endpoint
                ))

            await db.commit()

    async def bind_device_to_platform(self, bind_request: BindRequest) -> Optional[DevicePlatformBinding]:
        """绑定设备到平台"""
        try:
            # 首先取消设备的其他活跃绑定
            await self.unbind_device(bind_request.device_id)

            binding = DevicePlatformBinding(
                binding_id=str(uuid.uuid4()),
                device_id=bind_request.device_id,
                platform_id=bind_request.platform_id,
                bind_time=datetime.now(),
                is_active=True,
                bind_config=bind_request.bind_config or {}
            )

            async with aiosqlite.connect(self.db_path) as db:
                await db.execute('''
                    INSERT INTO device_platform_bindings 
                    (binding_id, device_id, platform_id, bind_time, is_active, bind_config)
                    VALUES (?, ?, ?, ?, ?, ?)
                ''', (
                    binding.binding_id, binding.device_id, binding.platform_id,
                    binding.bind_time, binding.is_active,
                    json.dumps(binding.bind_config)
                ))
                await db.commit()

            self.active_bindings[binding.device_id] = binding
            return binding

        except Exception as e:
            print(f"设备绑定失败: {e}")
            return None

    async def unbind_device(self, device_id: str, reason: str = None) -> bool:
        """解绑设备"""
        try:
            async with aiosqlite.connect(self.db_path) as db:
                await db.execute('''
                    UPDATE device_platform_bindings 
                    SET is_active = 0, unbind_time = ?
                    WHERE device_id = ? AND is_active = 1
                ''', (datetime.now(), device_id))
                await db.commit()

            if device_id in self.active_bindings:
                del self.active_bindings[device_id]

            print(f"设备解绑成功: {device_id}, 原因: {reason}")
            return True

        except Exception as e:
            print(f"设备解绑失败: {e}")
            return False

    async def unbind_specific(self, device_id: str, platform_id: str, reason: str = None) -> bool:
        """解绑特定平台的设备"""
        try:
            async with aiosqlite.connect(self.db_path) as db:
                await db.execute('''
                    UPDATE device_platform_bindings 
                    SET is_active = 0, unbind_time = ?
                    WHERE device_id = ? AND platform_id = ? AND is_active = 1
                ''', (datetime.now(), device_id, platform_id))
                await db.commit()

            if (device_id in self.active_bindings and
                    self.active_bindings[device_id].platform_id == platform_id):
                del self.active_bindings[device_id]

            return True

        except Exception as e:
            print(f"特定解绑失败: {e}")
            return False

    async def get_device_binding(self, device_id: str) -> Optional[DevicePlatformBinding]:
        """获取设备的当前绑定信息"""
        if device_id in self.active_bindings:
            return self.active_bindings[device_id]

        try:
            async with aiosqlite.connect(self.db_path) as db:
                async with db.execute('''
                    SELECT binding_id, device_id, platform_id, bind_time, unbind_time, is_active, bind_config
                    FROM device_platform_bindings 
                    WHERE device_id = ? AND is_active = 1
                    ORDER BY bind_time DESC LIMIT 1
                ''', (device_id,)) as cursor:
                    row = await cursor.fetchone()

                    if row:
                        binding = DevicePlatformBinding(
                            binding_id=row[0],
                            device_id=row[1],
                            platform_id=row[2],
                            bind_time=row[3],
                            unbind_time=row[4],
                            is_active=bool(row[5]),
                            bind_config=json.loads(row[6]) if row[6] else {}
                        )
                        self.active_bindings[device_id] = binding
                        return binding

        except Exception as e:
            print(f"获取设备绑定信息失败: {e}")

        return None

    async def get_platform_devices(self, platform_id: str) -> List[DevicePlatformBinding]:
        """获取平台下的所有设备绑定"""
        devices = []
        try:
            async with aiosqlite.connect(self.db_path) as db:
                async with db.execute('''
                    SELECT binding_id, device_id, platform_id, bind_time, unbind_time, is_active, bind_config
                    FROM device_platform_bindings 
                    WHERE platform_id = ? AND is_active = 1
                    ORDER BY bind_time DESC
                ''', (platform_id,)) as cursor:
                    rows = await cursor.fetchall()

                    for row in rows:
                        binding = DevicePlatformBinding(
                            binding_id=row[0],
                            device_id=row[1],
                            platform_id=row[2],
                            bind_time=row[3],
                            unbind_time=row[4],
                            is_active=bool(row[5]),
                            bind_config=json.loads(row[6]) if row[6] else {}
                        )
                        devices.append(binding)

        except Exception as e:
            print(f"获取平台设备失败: {e}")

        return devices

    async def get_binding_history(self, device_id: str) -> List[DevicePlatformBinding]:
        """获取设备的绑定历史"""
        history = []
        try:
            async with aiosqlite.connect(self.db_path) as db:
                async with db.execute('''
                    SELECT binding_id, device_id, platform_id, bind_time, unbind_time, is_active, bind_config
                    FROM device_platform_bindings 
                    WHERE device_id = ?
                    ORDER BY bind_time DESC
                ''', (device_id,)) as cursor:
                    rows = await cursor.fetchall()

                    for row in rows:
                        binding = DevicePlatformBinding(
                            binding_id=row[0],
                            device_id=row[1],
                            platform_id=row[2],
                            bind_time=row[3],
                            unbind_time=row[4],
                            is_active=bool(row[5]),
                            bind_config=json.loads(row[6]) if row[6] else {}
                        )
                        history.append(binding)

        except Exception as e:
            print(f"获取绑定历史失败: {e}")

        return history

    def get_all_platforms(self) -> List[PlatformInfo]:
        """获取所有平台信息"""
        return list(self.platforms.values())

    def get_platform(self, platform_id: str) -> Optional[PlatformInfo]:
        """获取特定平台信息"""
        return self.platforms.get(platform_id)

    async def add_platform(self, platform: PlatformInfo) -> bool:
        """添加新平台"""
        try:
            self.platforms[platform.platform_id] = platform

            async with aiosqlite.connect(self.db_path) as db:
                await db.execute('''
                    INSERT OR REPLACE INTO platforms 
                    (platform_id, platform_name, platform_type, version, description, api_endpoint)
                    VALUES (?, ?, ?, ?, ?, ?)
                ''', (
                    platform.platform_id, platform.platform_name, platform.platform_type,
                    platform.version, platform.description, platform.api_endpoint
                ))
                await db.commit()

            return True

        except Exception as e:
            print(f"添加平台失败: {e}")
            return False


# 全局绑定管理器实例
binding_manager = BindingManager()